package com.anysoft.base;

import android.annotation.TargetApi;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.CookieManager;
import android.webkit.JavascriptInterface;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.anysoft.R;
import com.anysoft.config.AppConstant;
import com.anysoft.config.HostConstant;
import com.anysoft.manager.PermissionManager;
import com.anysoft.ui.activity.PreViewFileActivity;
import com.anysoft.utils.ActivityCollector;
import com.anysoft.utils.LogUtil;
import com.anysoft.utils.StringUtil;
import com.anysoft.utils.ToastUtil;
import com.anysoft.widget.CustomWebView;
import com.anysoft.widget.HProgressBarLoading;
import com.facebook.drawee.view.SimpleDraweeView;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

import static android.view.View.GONE;
import static android.view.View.VISIBLE;

/**
 * Created by lty on 2017/12/27.
 */

public abstract class BaseWebViewActivity extends BaseActivity implements PermissionManager.OnPermissionListener {
    
    private final String TAG = this.getClass().getSimpleName();
    public String loadUrl;
    public Intent mIntent = new Intent();
    @BindView(R.id.leftButton)
    public Button leftButton;
    @BindView(R.id.rightButton)
    public TextView rightButton;
    @BindView(R.id.title)
    public TextView title;
    @BindView(R.id.normal_titlebar)
    public FrameLayout normal_titlebar;
    @BindView(R.id.iv_leftButton)
    public ImageView ivLeftButton;
    @BindView(R.id.logined_titlebar)
    public FrameLayout logined_titlebar;
    @BindView(R.id.sdv_logined_user_head)
    public SimpleDraweeView sdv_logined_user_head;
    @BindView(R.id.tv_logined_name)
    public TextView tv_logined_name;
    @BindView(R.id.tv_loginout)
    public TextView tv_loginout;
    @BindView(R.id.wv)
    public CustomWebView mWebView;
    @BindView(R.id.tv_item_web_error)
    public TextView tvItemWebError;
    @BindView(R.id.ll_item_web_error)
    public LinearLayout llItemWebError;
    @BindView(R.id.top_progress)
    public HProgressBarLoading top_progress;
    public boolean isLoadError = false;
    public String uploadUrl;
    private WebViewClient mWebViewClient = new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView webview, String url) {
            LogUtil.e(TAG, "shouldOverrideUrlLoading url=" + url);
            String params = "";
            if (url.contains("?") && url.indexOf("?") != url.length() - 1) {
                params = url.substring(url.indexOf("?") + 1);
            }
            onshouldOverrideUrlLoadingCallBack(webview, url, params);
            return true;
        }
        
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            LogUtil.e(TAG, "onPageStarted " + url);
        }
        
        @Override
        public void onPageFinished(WebView view, String url) {
        }
        
        @Override
        public void onLoadResource(WebView view, String url) {
            LogUtil.e(TAG, "onLoadResource " + view.getProgress());
            super.onLoadResource(view, url);
        }
        
        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            LogUtil.e(TAG, "onReceivedError" + view.getUrl());
            isLoadError = true;
            setShowErrorView(true);
            super.onReceivedError(view, request, error);
        }
        
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
            LogUtil.e(TAG, "onReceivedHttpError" + view.getUrl());
            isLoadError = true;
            setShowErrorView(true);
            super.onReceivedHttpError(view, request, errorResponse);
        }
        
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            handler.proceed();// 接受所有网站的证书
        }
    };
    private WebChromeClient mWebChromeClient = new WebChromeClient() {
        
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
            top_progress.setCurProgress(newProgress);
        }
        
        @Override
        public boolean onJsAlert(final WebView view, String url, final String message, JsResult result) {
            LogUtil.e(TAG, "onJsAlert:" + message);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    new AlertDialog.Builder(BaseWebViewActivity.this)
                            .setTitle("提示")
                            .setMessage(message)
                            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
//                                    view.reload();//重写刷新页面
                                
                                }
                            })
//                            .setNegativeButton("取消", null)
                            .show();
                    
                }
            });
            result.confirm();//这里必须调用，否则页面会阻塞造成假死
            return true;
        }
        
        @Override
        public boolean onJsConfirm(final WebView view, String url, final String message, JsResult result) {
            LogUtil.e(TAG, "onJsConfirm:" + message);
            result.confirm();//这里必须调用，否则页面会阻塞造成假死
            return true;
        }
        
        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
            LogUtil.e(TAG, "onJsPrompt:" + url);
            result.confirm();
            return true;
        }
    };
    
    /**
     * 将url转义转为map
     *
     * @param url
     * @return
     */
    public static HashMap<String, String> handleUrlParams(String url) {
        HashMap<String, String> hm = new HashMap<String, String>();
        try {
            url = URLDecoder.decode(url, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (url.contains("?") && url.indexOf("?") != url.length() - 1) {
            String params = url.substring(url.indexOf("?") + 1);
            if (params.contains("&")) {
                String[] paramArr = params.split("&");
                for (int i = 0; i < paramArr.length; i++) {
                    String str = paramArr[i];
                    if (str.contains("=")) {
                        hm.put(str.substring(0, str.indexOf("=")),
                                str.substring(str.indexOf("=") + 1,
                                        str.length()));
                    }
                }
            } else {
                if (params.contains("=")) {
                    hm.put(params.substring(0, params.indexOf("=")),
                            params.substring(params.indexOf("=") + 1,
                                    params.length()));
                }
            }
        }
        return hm;
    }
    
    /**
     * 通过key替换url中的值
     *
     * @param url
     * @return
     */
    public static String replaceUrlParams(String urlKey, String newValue, String urlParam) {
        StringBuilder urlBuild = new StringBuilder();
        try {
            if (!TextUtils.isEmpty(urlParam)) {
                if (urlParam.contains("&")) {
                    String[] strings = urlParam.split("&");
                    for (int i = 0; i < strings.length; i++) {
                        String[] split = strings[i].split("=");
                        for (int j = 0; j < split.length; j++) {
                            String value;
                            String key = split[0];
                            if (key.equals(urlKey)) {
                                value = newValue;
                            } else {
                                value = split[1];
                            }
                            urlBuild.append(key + "=" + value);
                            if (j != split.length - 1) {
                                urlBuild.append("&");
                            }
                            break;
                        }
                    }
                } else {
                    if (urlParam.contains("=")) {
                        String[] split = urlParam.split("=");
                        if (split[0].equals(urlKey)) {
                            urlBuild.append(split[0] + "=" + newValue);
                        } else {
                            urlBuild.append(split[0] + "=" + split[1]);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.e("lty", "replaceUrlParams: " + urlBuild.toString());
        return urlBuild.toString();
    }
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webview_base_layout);
        ButterKnife.bind(this);
        setShowErrorView(false);
        tvItemWebError.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mWebView.setVisibility(View.VISIBLE);
                llItemWebError.setVisibility(View.GONE);
                reLoadPage(loadUrl);
            }
        });
    }
    
    @Override
    protected void onResume() {
        if (mWebView != null) {
            mWebView.onResume();
        }
        super.onResume();
    }
    
    @Override
    protected void onPause() {
        if (mWebView != null) {
            mWebView.onPause();
        }
        super.onPause();
    }
    
    @Override
    protected void onDestroy() {
        if (mWebView != null) {
            //加载空内容
            mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
            mWebView.removeAllViews();
            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            mWebView.destroy();
            mWebView = null;
        }
        super.onDestroy();
    }
    
    public void setShowErrorView(boolean isLoadError) {
        if (isLoadError) {
            if (mWebView != null && llItemWebError != null) {
                llItemWebError.setVisibility(VISIBLE);
                mWebView.setVisibility(GONE);
            }
        } else {
            if (mWebView != null && llItemWebError != null) {
                llItemWebError.setVisibility(GONE);
                mWebView.setVisibility(VISIBLE);
            }
        }
    }
    
    public void reLoadPage(String url) {
        setWebViewConfig(url);
    }
    
    /**
     * @param url
     */
    public void setWebViewConfig(String url) {
        if (mWebView == null || StringUtil.isEmpty(url)) {
            LogUtil.e("url不能为空 或者 webview不能为空");
            return;
        }
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setDomStorageEnabled(true);
        webSettings.setAllowFileAccess(true);
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setSupportZoom(false);
        webSettings.setBuiltInZoomControls(false);
        webSettings.setDisplayZoomControls(false);
        webSettings.setDefaultTextEncodingName("UTF-8");
        webSettings.setAppCacheEnabled(true);
        webSettings.setDatabaseEnabled(true);
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webSettings.setMixedContentMode(
                    WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            webSettings.setAllowFileAccessFromFileURLs(true);
            webSettings.setAllowUniversalAccessFromFileURLs(true);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            CookieManager cookieManager = CookieManager.getInstance();
            cookieManager.setAcceptThirdPartyCookies(mWebView, true);
        }
        
        // TODO: 2018/1/19 防止通过file域来恶意攻击
        if (url.startsWith("file://")) {
            webSettings.setAllowFileAccess(false);
            webSettings.setJavaScriptEnabled(false);
            webSettings.setAllowFileAccessFromFileURLs(false);
            webSettings.setAllowUniversalAccessFromFileURLs(false);
        } else {
            webSettings.setJavaScriptEnabled(true);
            webSettings.setAllowFileAccess(true);
        }
        //设置本地调用对象及其接口
        mWebView.addJavascriptInterface(new JavaScriptObject(), "jsInvoke");
        mWebView.setWebViewClient(mWebViewClient);
        mWebView.setWebChromeClient(mWebChromeClient);
        if (url.startsWith("http")) {
            mWebView.loadUrl(url);
        } else {
            mWebView.loadDataWithBaseURL("about:blank", url, "text/html", "UTF-8", null);
        }
        mWebView.setOnLoadFinishListener(new CustomWebView.OnLoadFinishListener() {
            @Override
            public void onLoadFinish() {
                pageFinished();
            }
        });
        mWebView.removeJavascriptInterface("searchBoxJavaBridge_");
        mWebView.removeJavascriptInterface("accessibility");
        mWebView.removeJavascriptInterface("accessibiltyTraversal");
    }
    
    private void pageFinished() {
        String title = null;
        if (mWebView != null)
            title = mWebView.getTitle();
        if (!isLoadError) {
            setShowErrorView(false);
        } else {
            isLoadError = false;
            setShowErrorView(true);
        }
        
        if (!StringUtil.isEmpty(title) && ("网页无法打开".equals(title) || title.contains("404"))) {
            setShowErrorView(true);
        }
    }
    
    public abstract void onshouldOverrideUrlLoadingCallBack(WebView webview, String url, String params);
    
    public String generateUrl(String action, String param) {
        loadUrl = HostConstant.HOST_URL_H5_SERVER + action + ".html?isFromApp=true" + param;
        return loadUrl;
    }
    
    public void loadData(String content) {
        mWebView.loadDataWithBaseURL("about:blank", content, "text/html", "utf-8", null);
    }
    
    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
    
    @OnClick({R.id.leftButton, R.id.tv_loginout})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.leftButton:
                
                break;
            case R.id.tv_loginout:
                if (userInfoManager != null) {
                    ToastUtil.showShort("退出登录");
                    userInfoManager.signOut();
                }
                break;
            
        }
        finish();
    }
    
    public void isShowNormalTitleBar(boolean bool) {
        normal_titlebar.setVisibility(bool ? View.VISIBLE : View.GONE);
        logined_titlebar.setVisibility(bool ? View.GONE : View.VISIBLE);
    }
    
    /**
     * Open
     */
    @TargetApi(Build.VERSION_CODES.M)
    private void showFileAction() {
        if (PermissionManager.getInstance().checkPermissions(this, PermissionManager.PERMISSION_READ_WEITE_CAMERA)) {
            openFileChooser();
        } else {
            PermissionManager.getInstance().requestPermissions(this, PermissionManager.REQUEST_READ_WEITE_CAMERA,
                    PermissionManager.PERMISSION_READ_WEITE_CAMERA, this);
        }
    }
    
    private void openFileChooser() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("*/*");
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(intent, AppConstant.REQUEST_CHOOSEFILE);
    }
    
    @Override
    public void onPermissionSuccess() {
        openFileChooser();
    }
    
    @Override
    public void onPermissionFail() {
        ToastUtil.showShort("获取权限失败,请点击重试");
    }
    
    private void openFileViewActivity(String url) {
        mIntent.putExtra("url", url);
        ActivityCollector.startTargetActivity(this, PreViewFileActivity.class, mIntent);
    }
    
    public class JavaScriptObject {
        @JavascriptInterface
        public void uploadFileProxy(String url) {
            LogUtil.e("上传文件的url" + url);
            uploadUrl = url;
            showFileAction();
        }
        
        @JavascriptInterface
        public void openFileView(String url) {
            LogUtil.e("预览文件的url" + url);
            openFileViewActivity(url);
        }
    }
}
